#include "ImageProcessor.h"
#include "afterdetect.h"
#include "defectstatistics.h"
#include "detectcachemodel.h"
#include "errordialogmanager.h"
#include "ngtable.h"
#include "source/configmanager.h"
#include "source/logger.h"
#include <QMap>
#include <QVector>
#include <vector>
#include "cvalgedgedetection.h"

DetectCacheModel &DetectCacheModel::instance() {
    static DetectCacheModel instance;
    return instance;
}


void DetectCacheModel::displaycurrentCacheNum(int currentCacheNum)
{
    if(currentCacheNum_ != currentCacheNum)
    {
        currentCacheNum_ = currentCacheNum;
        emit currentCacheNumChange();
    }
}

void DetectCacheModel::addDataItem(ImageRecord imgCard) {
    QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全

    DataItem item;
    item.id = imgCard.getID();
    item.time = imgCard.getElapsedTime();
    LogTrack << " addDataItem imgCard.getState()" << imgCard.getState();
    if(imgCard.getState() == ImageRecord::Succeed)
    {
        std::vector<int> ngList = imgCard.getNgCard().getDefects();
        if(ngList.empty()) {
            item.isOK = true;
            item.detail = "良品";
        } else if(ngList.size() == 1 && ngList[0] == 26)
        {
            item.isOK = true;
            item.detail = "疑似分码";
        }  else {
            item.isOK = false;
            item.detail = NGTable::getInstance().parseNGListToDescription(ngList);
        }
    }else{
        item.isOK = true;
        item.detail = "故障 未进行完全检测";
    }

    item.detectStepInfo = imgCard.getdetectStepInfo();
    item.detectStepTime  = imgCard.getdetectStepTime();
    item.preProgeressImage = imgCard.getStepImage(StepProcess::Reprogress);
    item.mainImage = imgCard.getResultImage();
    item.ngCard = imgCard.getNgCard();
    //CardCacheItem CardItem;
    // CardItem.id = item.id;
    // CardItem.card = imgCard;
    //m_imgCardCache.append(CardItem);


    // if (m_imgCardCache.size() > m_cachequantity) {
    //     m_imgCardCache.removeFirst();
    // }
    LogTrack << "Added item id=" << item.id << " detail=" << item.detail;
    beginInsertRows(QModelIndex(), 0, 0); // 在模型的开始处插入新行
    m_cache.prepend(item); // 将新项目添加到开始处
    endInsertRows();

    if (m_cache.size() > m_cachequantity) {
        beginRemoveRows(QModelIndex(), m_cache.size() - 1, m_cache.size() - 1);
        m_cache.removeLast(); // 移除最后一项
        endRemoveRows();
    }
    displaycurrentCacheNum(item.id);
    float top,bottom;
    imgCard.getdistanceLargeSmall(top,bottom);
    int topmax = CvAlgEdgeDetection::getInstance().largeSmallUpperMax();
    int topmin = CvAlgEdgeDetection::getInstance().largeSmallUpperMin();
    int bottommax = CvAlgEdgeDetection::getInstance().largeSmallLowerMax();
    int bottommin = CvAlgEdgeDetection::getInstance().largeSmallLowerMin();

    //emit drawistanceLargeSmall(item.id,top,bottom);
    emit drawistanceLargeSmall(item.id,top,bottom,
                               topmax,topmin,bottommax,bottommin);


    //emit finishAddDetectCache(index , imgCard);
    index++;
}

QVariant DetectCacheModel::data(const QModelIndex &index, int role) const {
    QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
    if (!index.isValid() || index.row() >= m_cache.size()) {
        LogError << "Invalid index accessed: " << index.row();
        return QVariant();
    }

    const DataItem &item = m_cache.at(index.row());
    switch (role) {
    case IdRole:
        return item.id;
    case DetectDetailRole:
        return item.detail;
    case DetectTimeRole:
        return item.time;
    case DetectIsOKRole:
        return item.isOK;
    default:
        return QVariant();
    }
}

int DetectCacheModel::rowCount(const QModelIndex &parent) const {
    //LogDebug << "rowCount" << m_cache.size();
    return m_cache.size();
}

void DetectCacheModel::updateDefectById(int id, std::vector<int> defect) {
    // qDebug() << "12";

    //  qDebug() << "34";

    // 遍历 m_cache 查找对应的 DataItem
    for (int i = 0; i < m_cache.size(); ++i) {
        if (m_cache[i].id == id) {
            {
                QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
                DataItem &item = m_cache[i];

                // 更新 defect 信息
                if (defect.empty() ) {
                    item.isOK = true;
                    item.detail = "良品";
                } else if(defect.size() == 1 && defect[0] == 26)
                {
                    item.isOK = true;
                    item.detail = "疑似分码";
                } else {
                    item.isOK = false;
                    item.detail = NGTable::getInstance().parseNGListToDescription(defect);
                }
            }

            // 通知 QML 更新该行数据
            emit dataChanged(createIndex(i, 0), createIndex(i, 0), {DetectDetailRole, DetectIsOKRole});
            return;
        }
    }

    LogWarning << "No DataItem found with id=" << id;
}


QHash<int, QByteArray> DetectCacheModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[IdRole] = "id";
    roles[DetectDetailRole] = "detail";
    roles[DetectTimeRole] = "time";
    roles[DetectIsOKRole] = "isOK";
    return roles;
}

void DetectCacheModel::setCacheNum(int cacheNum) {
    QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
    if (cacheNum <= 0) {
        LogError << "Invalid cache number: " << cacheNum;
        return;
    }

    // 更新缓存数量设置
    cacheNum_ = cacheNum;
    ParamValue.setParameter("base","cachequantity", cacheNum_);
    LogDebug << "Cache number set to " << cacheNum;

    // 检查当前缓存大小是否大于新的缓存数量
    int excess = m_cache.size() - cacheNum_;
    if (excess > 0) {
        beginRemoveRows(QModelIndex(), 0, excess - 1);
        for (int i = 0; i < excess; ++i) {
            m_cache.removeFirst();
        }
        endRemoveRows();
        LogDebug << "Removed " << excess << " items from cache to fit new cache number.";
    }

    // excess = m_imgCardCache.size() - cacheNum_;
    // if (excess > 0) {
    //     for (int i = 0; i < excess; ++i) {
    //         m_imgCardCache.removeFirst();
    //     }
    // }
    emit currentCacheNumChange();
}

void DetectCacheModel::ClearCacheNum()
{
    QMutexLocker locker(&mutex_);
    okNum_ = 0;
    LogInfo << "Attempting to DetectCacheModel::ClearCacheNum ";
    if (!m_cache.isEmpty()) {
        beginRemoveRows(QModelIndex(), 0, m_cache.size() - 1);
        m_cache.clear();
        endRemoveRows();
    }

    // if (!m_imgCardCache.isEmpty()) {
    //     m_imgCardCache.clear();
    // }

    index = 0; // 重置索引
    displaycurrentCacheNum(index);
    emit clearDetectCache();
    emit currentCacheNumChange(); // 通知视图当前缓存数量已变化
}

void DetectCacheModel::DisplayCurrentSummary()
{
    QMap<int, std::vector<int>> currentSummary = AfterDetect::getInstance().getCurrentCache();
    QVector<QVector<int>> detects ;
    for (auto it = currentSummary.begin(); it != currentSummary.end(); ++it) {
        QVector<int> vec = QVector<int>::fromStdVector(it.value());
        detects.append(vec);
    }
    DefectStatistics::instance().setData(detects);
}

void DetectCacheModel::DisplayTotalSummary()
{
    QVector<std::vector<int>> TotalSummary = AfterDetect::getInstance().getTotalCache();
    QVector<QVector<int>> detects;

    for (const auto& vec : TotalSummary) {
        detects.append(QVector<int>(vec.begin(), vec.end())); // 使用迭代器构造 QVector<int>
    }
    DefectStatistics::instance().setData(detects);
}

void DetectCacheModel::DisplayFileSummary(QString filePath)
{
    LogDebug << "DisplayFileSummary: "<< filePath;
    QVector<QVector<int>> out_detects;
    QFile fileStream;
    fileStream.setFileName(filePath);
    if (!fileStream.open(QIODevice::ReadWrite | QIODevice::Text)) {
        LogError << "AfterDetect Failed to open file: " << filePath;
        ErrorDialogManager::instance().showNonBlockingError("查看总结失败","无法打开文件");
        return;
    }
    QByteArray data = fileStream.readAll();
    LogDebug << "DisplayFileSummary  get data: " << data.size();
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    fileStream.seek(0);
    QTextStream in(&fileStream);
    while (!in.atEnd()) {
        QString line = in.readLine();
        QJsonDocument doc = QJsonDocument::fromJson(line.toUtf8(), &parseError);
        if (doc.isNull() || !doc.isObject()) {
            LogDebug << "JSON parse error in line: " << parseError.errorString();
            continue; // 跳过错误行
        }
        QJsonObject obj = doc.object();
        QJsonArray defectsArray = obj["defects"].toArray();
        std::vector<int> defects;
        for (const QJsonValue &defectValue : defectsArray) {
            defects.push_back(defectValue.toInt());
        }
        out_detects.append(QVector<int>(defects.begin(), defects.end()));
    }
    DefectStatistics::instance().setData(out_detects);

}

void DetectCacheModel::outCSVFileSummary(QString filePath)
{
    LogDebug << "outCSVFileSummary: "<< filePath;
    QVector<QVector<int>> out_detects;
    QFile fileStream;
    fileStream.setFileName(filePath);
    if (!fileStream.open(QIODevice::ReadWrite | QIODevice::Text)) {
        LogError << "AfterDetect Failed to open file: " << filePath;
        ErrorDialogManager::instance().showNonBlockingError("查看总结失败","无法打开文件");
        return;
    }
    QByteArray data = fileStream.readAll();
    LogDebug << "DisplayFileSummary  get data: " << data.size();
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
    fileStream.seek(0);
    QTextStream in(&fileStream);
    while (!in.atEnd()) {
        QString line = in.readLine();
        QJsonDocument doc = QJsonDocument::fromJson(line.toUtf8(), &parseError);
        if (doc.isNull() || !doc.isObject()) {
            LogDebug << "JSON parse error in line: " << parseError.errorString();
            continue; // 跳过错误行
        }
        QJsonObject obj = doc.object();
        QJsonArray defectsArray = obj["defects"].toArray();
        std::vector<int> defects;
        for (const QJsonValue &defectValue : defectsArray) {
            defects.push_back(defectValue.toInt());
        }
        out_detects.append(QVector<int>(defects.begin(), defects.end()));
    }
    DefectStatistics::instance().exportDataToCSV(out_detects);
}

void DetectCacheModel::addOkNum()
{
    okNum_++;
    emit okNumChange();
}

void DetectCacheModel::clearOkNum()
{
    okNum_ =0;
}


void DetectCacheModel::displayImageRecordById(int id) {
    QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
    for (DataItem& item : m_cache) {
        if (item.id == id) {
            ImageProcessor::getInstance().setdisplayHistory(true);
            LogInfo<< "Retrieved ImageRecord with id=" << id;
            cv::Mat img = item.mainImage;
            ImageProcessor::getInstance().displayOKNGReson(item.ngCard);
            ImageProvider::getInstance().image2qml(img, "Main");
            // ImageProvider::getInstance().image2qml(imgCard.getbaseImage(), "Box1");
            ImageProvider::getInstance().image2qml(item.preProgeressImage, "Box1");
            ImageProcessor::getInstance().displaydetectStepTime(item.detectStepTime);
            ImageProcessor::getInstance().displaydetectStepInfo(item.detectStepInfo);
            return;
        }
    }
    LogWarning << "No ImageRecord found with id=" << id;
}

ImageRecord DetectCacheModel::getidImageCard(int id)
{

}

void DetectCacheModel::setcurrentCacheSeclectId( int id )
{
    if(id != currentCacheSeclectId_)
    {
        currentCacheSeclectId_ = id;
        displayImageRecordById(currentCacheSeclectId_);
        emit currentCacheSeclectIdChange();
    }
}

void DetectCacheModel::valueTableLoad() {
    setCacheNum(ParamValue.getParameter<int>("base","cachequantity"));
}


void DetectCacheModel::changeItemByID(int id, QString detail) {
    for (int i = 0; i < m_cache.size(); ++i) {
        if (m_cache[i].id == id) {
            {
                QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
                DataItem &item = m_cache[i];
                item.detail = detail; // 修改 detail 字段
            }

            // 通知 QML 更新该行数据
            emit dataChanged(createIndex(i, 0), createIndex(i, 0), {DetectDetailRole});
            LogDebug << "Updated item id=" << id << " with new detail=" << detail;
            return;
        }
    }

    LogWarning << "No DataItem found with id=" << id;
}

DetectCacheModel::DataItem& DetectCacheModel::getItemByID(int id) {
    QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全

    for (DataItem &item : m_cache) {
        if (item.id == id) {
            return item; // 返回引用
        }
    }
    DetectCacheModel::DataItem a;
    a.id = -1;
    LogWarning << "No DataItem found with id=" << id;
    //throw std::runtime_error("Item not found"); // 抛出异常或使用其他方式处理
}



DetectCacheModel::DetectCacheModel(QObject *parent) : QAbstractListModel(parent) {
    // Add some dummy data for debugging
    connect(&ConfigManager::getInstance(), &ConfigManager::valueTableLoad, this, &DetectCacheModel::valueTableLoad);
    cacheNum_ = ParamValue.getParameter<int>("base","cachequantity") > 0 ?
                    ParamValue.getParameter<int>("base","cachequantity")  : 1;

    currentCacheSeclectId_ = -1;
    index = 0;
    displaycurrentCacheNum(index);
}

void DetectCacheModel::inPlaceadjustCacheRemove34(int currentId, int offset)
{
    // 用来记录所有修改过的项的索引
    QVector<int> updatedIndexes;

    // 遍历 m_cache 中的项
    for (int i = 0; i < m_cache.size(); ++i) {
        // 检查 ID 是否在 currentId 和 currentId + offset 之间
        if (m_cache[i].id >= currentId && m_cache[i].id < currentId + offset) {
            // 获取缺陷列表
            std::vector<int> defect = m_cache[i].ngCard.getDefects();

            // 从 defect 中移除 34
            auto new_end = std::remove(defect.begin(), defect.end(), 34);
            if (new_end != defect.end()) {
                // 如果发生了修改
                defect.erase(new_end, defect.end());
                m_cache[i].ngCard.defects_ = defect ;  // 更新缺陷列表
                m_cache[i].detail = NGTable::getInstance().parseNGListToDescription(defect);
                dataChanged(createIndex(i, 0), createIndex(i, 0));
            }
        }
    }
}





void DetectCacheModel::inPlaceadjustCache(int currentId, int offset) {
    //QMutexLocker locker(&mutex_); // 锁定互斥量以保证线程安全
    qWarning() << "get Misalignment one inPlaceadjustCache" ;
    int insertIndex = -1;
    for (int i = 0; i < m_cache.size(); ++i) {
        if ( m_cache[i].id >= currentId - offset && m_cache[i].id <= currentId)
        {
            if(m_cache[i].id == (currentId - offset) && insertIndex == -1)
                insertIndex = i;
            m_cache[i].id += 1;
        }
    }

    // 创建新的 DataItem，插入到 currentId - offset 对应的位置
    DataItem newItem;
    newItem.id = currentId - offset; // 设定新项的 id
    newItem.isOK = false;            // 设定新项的状态
    newItem.detail = "错位";
    newItem.ngCard = NgCard();
    newItem.ngCard.addDefect(28);
    newItem.time = 0;
    // 如果找到了插入点，插入新的 DataItem
    if (insertIndex != -1) {
        m_cache.insert(insertIndex+1, newItem);
        m_cache.removeFirst();
    }

    if (insertIndex != -1) {
        emit dataChanged(createIndex(0, 0), createIndex(insertIndex+1, 0));
        LogDebug << "Cache adjusted and QML updated from index 0 to " << insertIndex;
    }
}

